#include "Helper.hpp"
#include <cstdarg>
#include <cstdlib>

namespace Welp
{
  string Format(const char* format, ...)
  {
    char buffer[4096];
    va_list args;
    va_start(args, format);
    vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);
    return buffer;
  }

  Exception::Exception(const string& message, ExceptionType::Enum type, const Location* location) :
    mMessage(message),
    mType(type)
  {
    if (location != nullptr)
    {
      mLocation = *location;
      mConsoleMessage = Format("%s(%d): Welp Error: %s\n", location->mOrigin.c_str(), location->mLine, message.c_str());
    }
    else
    {
      mConsoleMessage = mMessage;
    }
  }

  Exception::~Exception()
  {
  }

  void Exception::Print()
  {
    printf("%s", mConsoleMessage.c_str());
  }


  void GraphVisualizer::BeginDiGraph(const char* name)
  {
    mText += "digraph ";
    mText += name;
    mText += "\n{\n";
  }

  void GraphVisualizer::EndGraph()
  {
    mText += "}\n";
  }

  void GraphVisualizer::AddNode(const char* name, const char* label, const char* shape, const char* color)
  {
    mText += "  ";
    mText += name;
    mText += " [label=\"";
    mText += label;
    mText += "\" shape=\"";
    mText += shape;
    mText += "\" color=\"";
    mText += color;
    mText += "\"];\n";
  }

  void GraphVisualizer::AddEdge(const char* from, const char* to, const char* label, const char* style, const char* color)
  {
    mText += "  ";
    mText += from;
    mText += " -> ";
    mText += to;
    mText += " [label=\"";
    mText += label;
    mText += "\" style=\"";
    mText += style;
    mText += "\" color=\"";
    mText += color;
    mText += "\"];\n";
  }

  void GraphVisualizer::Visualize(const char* svgPath, const char* dotPath, const char* graphVizPath)
  {
    FILE* svgFile = fopen(dotPath, "w+");
    WelpErrorIf(svgFile == nullptr, "Could not open file to write to");
    fwrite(mText.c_str(), 1, mText.size(), svgFile);
    fclose(svgFile);

    string fullCommand = graphVizPath;
    fullCommand += " -Tsvg -o \"";
    fullCommand += svgPath;
    fullCommand += "\" \"";
    fullCommand += dotPath;
    fullCommand += "\"";

    auto result = system(fullCommand.c_str());

    system(svgPath);
  }
}